package manager.universe;

/**
 * UniverseManager est un runnable abstrait qui appel une fonction lockedRun.
 * A l'interrieur de cette fonction, l'univers est sécurisé et 
 * ne peu pas etre utilisé par d'autre thread.
 * @author Louis
 *
 */
public abstract class UniverseManager implements Runnable{
	
	private int periode;
	private volatile boolean isRunning;
	public UniverseManager(int periode){
		this.periode = periode;
		isRunning = true;
	}
	
	public final void run(){
		init();
		long before;
		long diff;
		while(isRunning()){
			before = System.nanoTime();
			lockedRun(Universe.getUniverse());
			Universe.release();
			diff = periode-(System.nanoTime()-before)/1000000;
			if(diff > 0){
				try {
					Thread.sleep(diff);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
		destroy();
	}
	
	protected abstract void lockedRun(Universe u);
	protected abstract void init();
	protected abstract void destroy();
	
	private boolean isRunning(){
		return isRunning;
	}
	
	public void kill(){
		isRunning = false;
	}
	
	public int getPeriode() {
		return periode;
	}
	
}
